<script setup lang="ts">
/**
 *  系统管理-系统数据-文件管理-文件编辑
 */
import {ElMessage, genFileId, type UploadInstance, type UploadProps, type UploadRawFile} from 'element-plus'
import {onMounted, ref} from 'vue'
import {FileTypeList} from '@/components/baseTs/fileType'
import {downloadFileApi, editFileApi, uploadFileApi} from '@/assets/api/systemManagement/data/file'
import type {DataFile} from "@/components/interface/data/dataFile";
import type {DataLabel} from "@/components/interface/data/dataLabel";


const props = defineProps<{
  form: DataFile,
  fileLabelList: DataLabel[]
}>()

const emits = defineEmits(['save', 'close'])

const upload = ref<UploadInstance>()
const fileUrl = ref('') // 回显的文件url

// 文件回显
const echoFile = () => {
  fileUrl.value = props.form.fileUrl
  downloadFileApi(props.form.fileUrl, props.form.type).then(res => {
    if (!(res.data instanceof Blob))
      ElMessage.error(res.data)
    const downloadFile = new File([res.data], props.form.name, {type: props.form.type})
    const file = downloadFile as UploadRawFile
    file.uid = genFileId()
    upload.value!.handleStart(file)
  })
}

// 切换文件
const handleExceed: UploadProps['onExceed'] = (files) => {
  upload.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  upload.value!.handleStart(file)
}

// 自定义上传文件处理
const beforeAvatarUpload: UploadProps['beforeUpload'] = (file) => {
  if (file.size > 1024 * 1024 * 10) {
    ElMessage.error({message: '上传文件大小不能超过 10MB!', showClose: true})
    return false
  }
  // 上传文件
  uploadFileApi(file, fileUrl.value).then(res => {
    if (res.data.code != 200) {
      ElMessage.error({message: res.data.data, showClose: true})
      return false
    }
    // 保存文件信息
    props.form.fileUrl = res.data.data
    editFileApi(props.form).then(res => {
      ElMessage.info(res.data.data)
      if (res.data.code === 200) {
        ElMessage.success({message: '保存成功', showClose: true})
        emits('save', true)
      } else
        ElMessage.error({message: res.data.data, showClose: true})
    })
  })
  return false // 返回false，阻止默认上传行为
}

// 表单验证
const formRef = ref()
const rules = {
  name: [
    {required: true, message: '请输入文件名称', trigger: 'blur'}
  ],
  type: [
    {required: true, message: '请选择文件类型', trigger: 'change'}
  ],
  labelId: [
    {required: true, message: '请选择文件标签', trigger: 'change'}
  ]
}

// 保存
const save = async (formRef: any) => {
  if (!formRef) return
  await formRef.validate(async (valid: any) => {
    if (valid) {
      upload.value!.submit()
    }
  })
}

onMounted(() => {
  echoFile()
})

</script>

<template>
  <div class="form-div">
    <div style="height: 80px">
      <el-upload
        ref="upload"
        class="upload-demo"
        action="#"
        :limit="1"
        :on-exceed="handleExceed"
        :auto-upload="false"
        :before-upload="beforeAvatarUpload"
      >
        <el-button type="primary">选择文件</el-button>
      </el-upload>
    </div>
    <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
      <el-form-item label="文件名称" prop="name">
        <el-input v-model="form.name" placeholder="请输入文件名称"/>
      </el-form-item>
      <el-form-item label="文件类型" prop="type">
        <el-select v-model="form.type" placeholder="请选择文件类型">
          <el-option v-for="item in FileTypeList" :key="item.value" :label="item.label"
                     :value="item.value"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="文件标签" prop="labelId">
        <el-select v-model="form.labelId" placeholder="请选择文件标签">
          <el-option v-for="item in props.fileLabelList" :key="item.id" :label="item.name"
                     :value="item.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="form.remark" placeholder="请输入备注"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="save(formRef)">保存</el-button>
        <el-button @click="$emit('close')">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<style scoped>

</style>
